home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / tools / czesc_2 / interfaces / willy-ttx / quicksort-source / quicksort.c < prev   
C/C++ Source or Header  |  1992-11-24  |  9KB  |  348 lines

  1. /** quicksort.c
  2. *
  3. *   Originally, a test program to demonstrate the direct variable interface
  4. *   to ARexx, by William Hawes. From the original docs:
  5. *   "Opens a public port called "VarTest" and then waits for REXX messages.
  6. *    The port stays open until a "CLOSE" command is received.
  7. *    Usage:  run vartest
  8. *    Then send commands from within ARexx by "address 'VarTest' command" "
  9. *
  10. *   Converted to Manx by WGL
  11. *   Converted to a QuickSort command host by Marvin Weinstein.
  12. *   Converted back to SAS by WGL
  13. *
  14. *   Added a List Requester, and the QuickSort now really is an insertion
  15. *   sort (easier with Lists), to be used with Spellfix.ttx and ISpell. WGL.
  16. *
  17. *   Recent change: changed the "QUIT" command to QS_QUIT, to make it not
  18. *   interfere with QUIT commands for other hosts. CLOSE is now QS_CLOSE.
  19. *
  20. **/
  21. /*
  22. *   Standard includes for SAS C.
  23. */
  24. #include <exec/types.h>
  25. #include <exec/exec.h>
  26. #include <intuition/intuitionbase.h>
  27. #include <intuition/gadgetclass.h>
  28. #include <libraries/gadtools.h>
  29. #include <graphics/gfxbase.h>
  30. #include <graphics/text.h>
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include <ctype.h>
  35. #include <proto/rexxsys.h>
  36. #include <proto/all.h>
  37.  
  38. /*
  39. *   Prototypes for functions defined in RexxVars.o
  40. */
  41. long __stdargs SetRexxVar(struct RexxMsg *, unsigned char *, unsigned char *,
  42.                           long);
  43. long __stdargs GetRexxVar(struct RexxMsg *, unsigned char *, STRPTR *, long);
  44.  
  45. long __stdargs CheckRexxMsg(struct RexxMsg *);
  46.  
  47. static long Sort(struct List *);
  48. static void ReturnMsg(struct RexxMsg *, long, long);
  49. static struct List *AddList(struct List *, char *, long);
  50. static struct List *NukeList(struct List *);
  51. static struct List *GetRexxList(struct RexxMsg *, long);
  52. static struct List *PutRexxList(struct RexxMsg *, struct List *);
  53.  
  54. struct Node *ListRequest(struct Screen *, struct List *, long, long, long, long);
  55.  
  56. struct RexxLib *RexxSysBase         = NULL;
  57. struct IntuitionBase *IntuitionBase = NULL;
  58. struct GfxBase *GfxBase             = NULL;
  59. struct Library *GadToolsBase        = NULL;
  60.  
  61. #define DO_SORT 1
  62. #define NO_SORT 0
  63.  
  64. void main(int argc, char **argv)
  65. {
  66.    struct MsgPort *MyPort = NULL;
  67.    struct RexxMsg *rmptr;
  68.    long           quitflag = 0, sortflag;
  69.    long           res1, res2, x = 0, y = 0, w = 0, h = 0, n;
  70.    struct List    *list = NULL;
  71.    struct Node    *result;
  72.    char           *screenname = NULL, *flags = NULL, *ptr;
  73.    struct Screen  *screen = NULL;
  74.  
  75.    RexxSysBase = (struct RexxLib *) OpenLibrary("rexxsyslib.library",0);
  76.    if (RexxSysBase == 0L) goto cleanup;
  77.  
  78.    IntuitionBase = (struct RexxLib *) OpenLibrary("intuition.library",0);
  79.    if (IntuitionBase == 0L) goto cleanup;
  80.  
  81.    GfxBase = (struct RexxLib *) OpenLibrary("graphics.library",0);
  82.    if (GfxBase == 0L) goto cleanup;
  83.  
  84.    GadToolsBase = (struct RexxLib *) OpenLibrary("gadtools.library",0);
  85.    if (GadToolsBase == 0L) goto cleanup;
  86. /*
  87. *   Really should have used all upper case here, but too late now. WGL
  88. */
  89.    MyPort = CreatePort("QuickSortPort", NULL);
  90.    if (MyPort == NULL) goto cleanup;
  91.  
  92.    while (quitflag == 0) {
  93.       Wait(1L << MyPort->mp_SigBit);
  94.  
  95.       rmptr = (struct RexxMsg *) GetMsg(MyPort);
  96.  
  97.       res1 = res2 = 0L;
  98.       if (CheckRexxMsg(rmptr)) {
  99.          if (stricmp(rmptr->rm_Args[0], "QSORT") == 0) {
  100.             if ((rmptr->rm_Action & 0xFF) == 3) {
  101. /*
  102. *   Get the strings array using insertion sort
  103. */
  104.                list = GetRexxList(rmptr, DO_SORT);
  105. /*
  106. *   Now put them back.
  107. */
  108.                if (list) list = PutRexxList(rmptr, list);
  109.  
  110.                if (list == NULL) {
  111.                   res1 = 10L;
  112.                   res2 = 12L;
  113.                }
  114.  
  115.                list = NukeList(list);
  116.             }
  117.             else {
  118.                res1 = 10;
  119.                res2 = 17;
  120.             }
  121.          }
  122.          else if (stricmp(rmptr->rm_Args[0], "LISTREQUEST") == 0) {
  123.             if ((n = (rmptr->rm_Action & 0xFF)) < 4) {
  124.                res1 = 10;
  125.                res2 = 17;
  126.             }
  127.             else {
  128.                if (n >= 5)  x = atol(rmptr->rm_Args[5]);
  129.                if (n >= 6)  y = atol(rmptr->rm_Args[6]);
  130.                if (n >= 7)  w = atol(rmptr->rm_Args[7]);
  131.                if (n >= 8)  h = atol(rmptr->rm_Args[8]);
  132.                if (n >= 9)  screenname = rmptr->rm_Args[9];
  133.                if (n >= 10) flags      = rmptr->rm_Args[10];
  134.  
  135.                sortflag = NO_SORT;
  136.                if (flags && (stricmp(flags, "SORT") == 0)) sortflag = DO_SORT;
  137.  
  138.                list = GetRexxList(rmptr, sortflag);
  139.  
  140.                if (list) {
  141.                   if (screenname) screen = LockPubScreen(screenname);
  142.  
  143.                   result = ListRequest(screen, list, x, y, w, h);
  144.  
  145.                   if (screen) UnlockPubScreen(NULL, screen);
  146.  
  147.                   if (result) ptr = result->ln_Name;
  148.                   else        ptr = "";
  149.  
  150.                   SetRexxVar(rmptr, rmptr->rm_Args[4], ptr, strlen(ptr));
  151.  
  152.                   list = NukeList(list);
  153.                }
  154.                else {
  155.                   res1 = 10L;
  156.                   res2 = 12L;
  157.                }
  158.             }
  159.          }
  160. /*
  161. *   See whether it's the close command
  162. */
  163.          else if (strcmp(rmptr->rm_Args[0], "QS_CLOSE") == 0) {
  164.             quitflag = 1;
  165.          }
  166.          else if (strcmp(rmptr->rm_Args[0], "QS_QUIT") == 0) {
  167.             quitflag = 1;
  168.          }
  169.          else {
  170.             res1 = 5;
  171.             res2 = 1;
  172.          }
  173.       }
  174.       else {
  175.          res1 = 10;
  176.          res2 = 10;
  177.       }
  178. /*
  179. *   If we get here, we handled the command, but didn't return yet.
  180. */
  181.       ReturnMsg(rmptr, res1, res2);
  182.    }
  183.  
  184. cleanup:
  185.    if (MyPort)        DeletePort(MyPort);
  186.    if (RexxSysBase)   CloseLibrary(RexxSysBase);
  187.    if (GadToolsBase)  CloseLibrary(GadToolsBase);
  188.    if (GfxBase)       CloseLibrary(GfxBase);
  189.    if (IntuitionBase) CloseLibrary(IntuitionBase);
  190.  
  191.    exit(0);
  192. }
  193.  
  194.  
  195. static struct List *GetRexxList(rmptr, sortflag)
  196. struct RexxMsg *rmptr;
  197. long sortflag;
  198. {
  199.    long left, right, i, error;
  200.    char buffer[256];
  201.    STRPTR value;
  202.    struct List *list = NULL;
  203. /*
  204. *   Get left and right bounds of string array to be sorted
  205. */
  206.    left  = atoi(rmptr->rm_Args[1]);
  207.    right = atoi(rmptr->rm_Args[2]);
  208. /*
  209. *   Copy RexxVariable array into strings
  210. */
  211.    for (i = left; i <= right; i++) {
  212. /*
  213. *   Put name of stem in buffer
  214. */
  215.       sprintf(buffer, "%s.%d", rmptr->rm_Args[3], i);
  216. /*
  217. *   Now get the string from the program
  218. */
  219.       error = GetRexxVar(rmptr, buffer, &value, 256);
  220.       if (error) {
  221.          list = NukeList(list);
  222.          break;
  223.       }
  224.       list = AddList(list, (char *) value, sortflag);
  225.    }
  226.    return(list);
  227. }
  228.  
  229.  
  230. static struct List *PutRexxList(rmptr, list)
  231. struct RexxMsg *rmptr;
  232. struct List *list;
  233. {
  234.    long left, right, i, error;
  235.    char buffer[256], *ptr;
  236.    struct Node *n;
  237. /*
  238. *   Get left and right bounds of string array to be sorted
  239. */
  240.    left  = atoi(rmptr->rm_Args[1]);
  241.    right = atoi(rmptr->rm_Args[2]);
  242. /*
  243. *   Put sort ed array back in old stem variable
  244. */
  245.    for (i = left, n = list->lh_Head; i <= right; i++, n = n->ln_Succ) {
  246. /*
  247. *   Put name of stem in buffer
  248. */
  249.       sprintf(buffer, "%s.%d", rmptr->rm_Args[3], i);
  250.       ptr = n->ln_Name;
  251. /*
  252. *   Now get the string from the program
  253. */
  254.       error = SetRexxVar(rmptr, buffer, ptr, strlen(ptr));
  255.       if (error) {
  256.          list = NukeList(list);
  257.          break;
  258.       }
  259.    }
  260.    return(list);
  261. }
  262.  
  263.  
  264. static void ReturnMsg(rmptr, res1, res2)
  265. struct RexxMsg *rmptr;
  266. long res1, res2;
  267. {
  268.    rmptr->rm_Result1 = res1;
  269.    rmptr->rm_Result2 = res2;
  270.    ReplyMsg(rmptr);
  271.    return;
  272. }
  273.  
  274. /**
  275. *
  276. *   Some list utility functions.
  277. *   AddList adds a string to an Exec list. If the list doesn't exist
  278. *   yet, it is first created. If sortflag is true, the list is sorted
  279. *   using insertion sort.
  280. *   NukeList deletes an entire list created by AddList.
  281. *
  282. **/
  283. #define LSIZE ((long) sizeof(struct List))
  284. #define NSIZE ((long) sizeof(struct Node))
  285.  
  286. static struct List *AddList(list, s, sortflag)
  287. struct List *list;
  288. char *s;
  289. long sortflag;
  290. {
  291.    struct Node *n, *nt;
  292.    char *ptr;
  293.  
  294.    if (list == NULL) {
  295.       list = AllocMem(LSIZE, MEMF_CLEAR);
  296.       if (list == NULL) return(NULL);
  297.       NewList(list);
  298.    }
  299.  
  300.    if (s) {
  301.       n = AllocMem(NSIZE, MEMF_CLEAR);
  302.       if (n == NULL) return(NukeList(list));
  303.  
  304.       ptr = AllocMem(strlen(s) + 1, 0L);
  305.       if (ptr == NULL) return(NukeList(list));
  306.  
  307.       strcpy(ptr, s);
  308.       n->ln_Name = ptr;
  309.  
  310.       if (sortflag) {
  311.          nt = list->lh_Head;
  312.          while (nt->ln_Succ) {
  313.             if (stricmp(nt->ln_Name, ptr) >= 0) break;
  314.             nt = nt->ln_Succ;
  315.          }
  316.          Insert(list, n, nt->ln_Pred);
  317.       }
  318.       else {
  319.          AddTail(list, n);
  320.       }
  321.    }
  322.  
  323.    return(list);
  324. }
  325.  
  326. static struct List *NukeList(list)
  327. struct List *list;
  328. {
  329.    struct Node *n, *nn;
  330.    char *ptr;
  331.  
  332.    if (list) {
  333.       if (list != (struct List *) list->lh_TailPred) {
  334.          n = list->lh_Head;
  335.          while (nn = n->ln_Succ) {
  336.             Remove(n);
  337.             if (ptr = n->ln_Name) FreeMem(ptr, strlen(ptr) + 1);
  338.             FreeMem(n, NSIZE);
  339.             n = nn;
  340.          }
  341.       }
  342.       FreeMem(list, LSIZE);
  343.    }
  344.    return(NULL);
  345. }
  346.  
  347.  
  348.